Passed
Push — master ( 7d3761...2cddad )
by Rafael S.
01:29
created

to-bytes.js ➔ writeBytes   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
c 2
b 0
f 0
nc 9
nop 3
dl 0
loc 21
rs 8.7624
1
/*
2
 * to-bytes: bytes to numbers and strings.
3
 * Copyright (c) 2017 Rafael da Silva Rocha.
4
 * https://github.com/rochars/byte-data
5
 */
6
7
const writer = require("../src/write-bytes.js");
8
const helpers = require("../src/helpers.js");
9
const bitDepthLib = require("../src/bit-depth.js");
10
11
/**
12
 * Turn numbers and strings to bytes.
13
 * @param {!Array<number>|number|string} values The data.
14
 * @param {number} bitDepth The bit depth of the data.
15
 *   Possible values are 1, 2, 4, 8, 16, 24, 32, 40, 48 or 64.
16
 * @param {Object} options The options:
17
 *   - "float": True for floating point numbers. Default is false.
18
 *       This option is available for 16, 32 and 64-bit numbers.
19
 *   - "signed": True for signed values. Default is false.
20
 *   - "base": The base of the output. Default is 10. Can be 2, 10 or 16.
21
 *   - "char": If the bytes represent a string. Default is false.
22
 *   - "be": If the values are big endian. Default is false (little endian).
23
 *   - "buffer": If the bytes should be returned as a Uint8Array.
24
 *       Default is false (bytes are returned as a regular array).
25
 * @return {!Array<number>|!Array<string>|Uint8Array} the data as a byte buffer.
26
 */
27
function toBytes(values, bitDepth, options={"base": 10, "signed": false}) {
28
    if (bitDepth == 64) {
29
        options.float = true;
30
    }
31
    if (options.float) {
32
        options.signed = true;
33
    }
34
    options.bits = bitDepth;
35
    values = helpers.turnToArray(values);
36
    let bytes = writeBytes(values, options, bitDepth);
37
    helpers.makeBigEndian(bytes, options.be, bitDepth);
38
    helpers.outputToBase(bytes, bitDepth, options.base);
39
    helpers.fixFloat16Endianness(bytes, options);
40
    if (options.buffer) {
41
        bytes = new Uint8Array(bytes);
42
    }
43
    return bytes;
44
}
45
46
/**
47
 * Write values as bytes.
48
 * @param {!Array<number>|number|string} values The data.
49
 * @param {Object} options The options according to the type.
50
 * @param {number} bitDepth The bitDepth of the data.
51
 * @return {!Array<number>} the bytes.
52
 */
53
function writeBytes(values, options, bitDepth) {
54
    let bitWriter;
55
    if (options.char) {
56
        bitWriter = writer.writeString;
57
    } else {
58
        bitWriter = writer['write' + bitDepth + 'Bit' + (options.float ? "Float" : "")];
59
    }
60
    let i = 0;
61
    let j = 0;
62
    let len = values.length;
63
    let bytes = [];
64
    let minMax = getBitDepthMinMax(options, bitDepth);
65
    while (i < len) {
66
        if (!options.float) {
67
            checkOverflow(values, i, minMax.min, minMax.max);
68
        }
69
        j = bitWriter(bytes, values, i, j, options.signed);
70
        i++;
71
    }
72
    return bytes;
73
}
74
75
/**
76
 * Get the minimum and maximum values accordind to the type.
77
 * @param {Object} options The options according to the type.
78
 * @param {number} bitDepth The bit depth of the data.
79
 * @return {Object}
80
 */
81
function getBitDepthMinMax(options, bitDepth) {
82
    let minMax = {};
83
    if (options.signed) {
84
        minMax.max = (bitDepthLib.BitDepthMaxValues[bitDepth] / 2) - 1;
85
        minMax.min = (bitDepthLib.BitDepthMaxValues[bitDepth] / 2) * -1;
86
    } else {
87
        minMax.max = bitDepthLib.BitDepthMaxValues[bitDepth] - 1;
88
        minMax.min = 0;
89
    }
90
    return minMax;
91
}
92
93
/**
94
 * Limit the value according to the bit depth in case of
95
 * overflow or underflow.
96
 * @param {!Array<number>|number|string} values The data.
97
 * @param {number} index The index of the value in the array.
98
 * @param {number} min The minimum value.
99
 * @param {number} max The maximum value.
100
 */
101
function checkOverflow(values, index, min, max) {
102
    if (values[index] > max) {
103
        values[index] = max;
104
    } else if(values[index] < min) {
105
        values[index] = min;
106
    }
107
}
108
109
module.exports.toBytes = toBytes;
110